/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.cef.generator.entityGenerator.base.dataTypeData.nestedConfigs;

import com.inspur.edp.caf.generator.baseInfo.TypeInfo;
import com.inspur.edp.caf.generator.property.ClassPropertyGenerator;
import com.inspur.edp.cef.designtime.api.IGspCommonDataType;
import com.inspur.edp.cef.designtime.api.IGspCommonField;
import com.inspur.edp.cef.generator.entityGenerator.base.dataTypeData.DataTypeDataGeneratorContext;
import com.inspur.edp.udt.designtime.api.entity.UnifiedDataTypeDef;
import lombok.var;
import org.eclipse.jdt.core.dom.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public abstract class NestedMappingGenerator extends ClassPropertyGenerator
{
	protected IGspCommonDataType dataType;
	protected IGspCommonField field;
	protected DataTypeDataGeneratorContext dataGenContext;
	protected UnifiedDataTypeDef udt;
	public NestedMappingGenerator(IGspCommonDataType dataType, IGspCommonField field, UnifiedDataTypeDef udt, DataTypeDataGeneratorContext dataGenContext)
	{
		this.dataGenContext = dataGenContext;
		this.dataType = dataType;
		this.field = field;
		this.udt = udt;
	}

	@Override
	protected ArrayList<Modifier.ModifierKeyword> getGetterAccessModifier()
	{
		return new ArrayList<Modifier.ModifierKeyword>(Arrays.asList(new Modifier.ModifierKeyword[] { Modifier.ModifierKeyword.PUBLIC_KEYWORD}));
	}
	@Override
	protected ArrayList<Modifier.ModifierKeyword> getSetterAccessModifier() {
		return null;
	}
	@Override
	protected String getFieldName() {
		return null;
	}
	@Override
	protected String  getPropertyName()
	{
		return "Mapping";
	}

	@Override
	protected TypeInfo getPropertyType()
	{
		TypeInfo typeInfo = new TypeInfo("HashMap");
		typeInfo.setTypePackageName("java.util");
		typeInfo.setIsParameterizedType(true);

		TypeInfo argType1 = new TypeInfo("String");
		TypeInfo argType2 = new TypeInfo("String");
		ArrayList<TypeInfo> args = new ArrayList<TypeInfo>(Arrays.asList(new TypeInfo[]{argType1,argType2}));
		typeInfo.setArguments(args);
		return typeInfo;
	}

	@Override
	protected boolean  hasSetMethod()
	{
		return false;
	}

	protected final Block getMappingBolck(HashMap<String, String> mapping)
	{
		Block block = ast.newBlock();
		block.statements().addAll(getMappingStatements(mapping));
		return block;
	}

	private ArrayList<Statement> getMappingStatements(HashMap<String, String> mapping)
	{
		ArrayList<Statement> list = new ArrayList<Statement>();
		list.add(getMappingDeclare());

		for (Map.Entry<String, String> item : mapping.entrySet())
		{
			list.add(getMappingItemStatement(item));
		}
		list.add(getReturnStatement());
		return list;
	}

	private Statement getMappingItemStatement(Map.Entry<String, String> item)
	{
		MethodInvocation invocation = ast.newMethodInvocation();
		invocation.setName(ast.newSimpleName("put"));
		invocation.setExpression(ast.newSimpleName("mapping"));
		StringLiteral arg1 = ast.newStringLiteral();
		arg1.setLiteralValue(item.getKey());
		StringLiteral arg2 = ast.newStringLiteral();
		arg2.setLiteralValue(item.getValue());
		invocation.arguments().add(arg1);
		invocation.arguments().add(arg2);

		return ast.newExpressionStatement(invocation);
	}

	private Statement getMappingDeclare()
	{
		ParameterizedType type = ast.newParameterizedType(ast.newSimpleType(ast.newSimpleName("HashMap")));
		type.typeArguments().add(ast.newSimpleType(ast.newSimpleName("String")));
		type.typeArguments().add(ast.newSimpleType(ast.newSimpleName("String")));

		VariableDeclarationFragment frag =ast.newVariableDeclarationFragment();
		frag.setName(ast.newSimpleName("mapping"));
		ClassInstanceCreation instance = ast.newClassInstanceCreation();
		instance.setType(type);
		frag.setInitializer(instance);

		VariableDeclarationStatement statement = ast.newVariableDeclarationStatement(frag);
		ParameterizedType type1 = ast.newParameterizedType(ast.newSimpleType(ast.newSimpleName("HashMap")));
		type1.typeArguments().add(ast.newSimpleType(ast.newSimpleName("String")));
		type1.typeArguments().add(ast.newSimpleType(ast.newSimpleName("String")));
		statement.setType(type1);

		return statement;
//		return SyntaxFactory.LocalDeclarationStatement(SyntaxFactory.VariableDeclaration(TypeUtils.getTypeSyntax(java.util.HashMap<String, String>.class)).WithVariables(SyntaxFactory.<VariableDeclaratorSyntax>SingletonSeparatedList(SyntaxFactory.VariableDeclarator(SyntaxFactory.Identifier("mapping")).WithInitializer(SyntaxFactory.EqualsValueClause(SyntaxFactory.ObjectCreationExpression(TypeUtils.getTypeSyntax(java.util.HashMap<String, String>.class)).WithArgumentList(SyntaxFactory.ArgumentList()))))));
	}

	private Statement getReturnStatement()
	{
		ReturnStatement returnStatment = ast.newReturnStatement();
		returnStatment.setExpression(ast.newSimpleName("mapping"));
		return returnStatment;
	}
}
